package bourne.com.office;

import java.io.File;

import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.ComThread;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;


/**
 * 
 * @Description:  
 * 	通过jacob调用vba宏，转化office文档
 * 	doc docx xls xlsx ppt 2 pdf
 * 	doc2docx
 * 	docx2doc
 * @author bourne
 * @date 2017年7月21日-下午11:09:38
 * @version V1.0
 */
public class Convert {

	/* 转PDF格式值 */
	private static final int wdFormatPDF = 17;
	private static final int xlFormatPDF = 0;
	private static final int ppFormatPDF = 32;

	/* 目标格式 */
	private String destType;
	private boolean isIndent = false;

	public boolean convert2PDF(String inputFile, String pdfFile) {
		String suffix = getFileSufix(inputFile);
		File file = new File(inputFile);
		if (!file.exists()) {
			System.out.println("文件不存在！");
			return false;
		}
		if (suffix.equals("pdf")) {
			System.out.println(inputFile + " PDF not need to convert!");
			return false;
		}
		if (suffix.equals("doc") || suffix.equals("docx") || suffix.equals("txt")) {
			return word2PDF(inputFile, pdfFile);
		} else if (suffix.equals("ppt") || suffix.equals("pptx")) {
			return ppt2PDF(inputFile, pdfFile);
		} else if (suffix.equals("xls") || suffix.equals("xlsx")) {
			return excel2PDF(inputFile, pdfFile);
		} else {
			System.out.println("文件格式不支持转换!");
			return false;
		}
	}

	/**
	 * 获取文件后缀
	 * 
	 * @param fileName
	 * @return
	 * @author SHANHY
	 */
	private String getFileSufix(String fileName) {
		int splitIndex = fileName.lastIndexOf(".");
		return fileName.substring(splitIndex + 1);
	}

	private String getNameWithoutSuffix(String fileName) {
		int pos = fileName.lastIndexOf(".");
		return fileName.substring(0, pos);
	}

	/**
	 * Word文档转换
	 * 
	 * @param inputFile
	 * @param pdfFile
	 * @author SHANHY
	 */
	private boolean word2PDF(String inputFile, String pdfFile) {
		ComThread.InitSTA();

		long start = System.currentTimeMillis();
		ActiveXComponent app = null;
		Dispatch doc = null;
		try {
			app = new ActiveXComponent("Word.Application");// 创建一个word对象
			app.setProperty("Visible", new Variant(false)); // 不可见打开word
			app.setProperty("AutomationSecurity", new Variant(3)); // 禁用宏
			Dispatch docs = app.getProperty("Documents").toDispatch();// 获取文挡属性

			System.out.println("打开文档 >>> " + inputFile);
			// Object[]第三个参数是表示“是否只读方式打开”
			// 调用Documents对象中Open方法打开文档，并返回打开的文档对象Document
			doc = Dispatch.call(docs, "Open", inputFile, false, true).toDispatch();
			// 调用Document对象的SaveAs方法，将文档保存为pdf格式
			System.out.println("转换文档 [" + inputFile + "] >>> [" + pdfFile + "]");
			Dispatch.call(doc, "SaveAs", pdfFile, wdFormatPDF);// word保存为pdf格式宏，值为17
			// Dispatch.call(doc, "ExportAsFixedFormat", pdfFile, wdFormatPDF);
			// // word保存为pdf格式宏，值为17

			long end = System.currentTimeMillis();

			System.out.println("用时：" + (end - start) + "ms.");
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("========Error:文档转换失败：" + e.getMessage());
		} finally {
			Dispatch.call(doc, "Close", false);
			System.out.println("关闭文档");
			if (app != null)
				app.invoke("Quit", new Variant[] {});
		}
		// 如果没有这句话,winword.exe进程将不会关闭
		ComThread.Release();
		ComThread.quitMainSTA();
		return false;
	}

	/**
	 * PPT文档转换
	 * 
	 * @param inputFile
	 * @param pdfFile
	 * @author SHANHY
	 */
	private boolean ppt2PDF(String inputFile, String pdfFile) {
		ComThread.InitSTA();

		long start = System.currentTimeMillis();
		ActiveXComponent app = null;
		Dispatch ppt = null;
		try {
			app = new ActiveXComponent("PowerPoint.Application");// 创建一个PPT对象
			// app.setProperty("Visible", new Variant(false)); //
			// 不可见打开（PPT转换不运行隐藏，所以这里要注释掉）
			// app.setProperty("AutomationSecurity", new Variant(3)); // 禁用宏
			Dispatch ppts = app.getProperty("Presentations").toDispatch();// 获取文挡属性

			System.out.println("打开文档 >>> " + inputFile);
			// 调用Documents对象中Open方法打开文档，并返回打开的文档对象Document
			ppt = Dispatch.call(ppts, "Open", inputFile, true, // ReadOnly
					true, // Untitled指定文件是否有标题
					false// WithWindow指定文件是否可见
			).toDispatch();

			System.out.println("转换文档 [" + inputFile + "] >>> [" + pdfFile + "]");
			Dispatch.call(ppt, "SaveAs", pdfFile, ppFormatPDF);

			long end = System.currentTimeMillis();

			System.out.println("用时：" + (end - start) + "ms.");

			return true;
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("========Error:文档转换失败：" + e.getMessage());
		} finally {
			Dispatch.call(ppt, "Close");
			System.out.println("关闭文档");
			if (app != null)
				app.invoke("Quit", new Variant[] {});
		}
		ComThread.Release();
		ComThread.quitMainSTA();
		return false;
	}

	/**
	 * Excel文档转换
	 * 
	 * @param inputFile
	 * @param pdfFile
	 * @author SHANHY
	 */
	private boolean excel2PDF(String inputFile, String pdfFile) {
		ComThread.InitSTA();

		long start = System.currentTimeMillis();
		ActiveXComponent app = null;
		Dispatch excel = null;
		try {
			app = new ActiveXComponent("Excel.Application");// 创建一个PPT对象
			app.setProperty("Visible", new Variant(false)); // 不可见打开
			// app.setProperty("AutomationSecurity", new Variant(3)); // 禁用宏
			Dispatch excels = app.getProperty("Workbooks").toDispatch();// 获取文挡属性

			System.out.println("打开文档 >>> " + inputFile);
			// 调用Documents对象中Open方法打开文档，并返回打开的文档对象Document
			excel = Dispatch.call(excels, "Open", inputFile, false, true).toDispatch();
			// 调用Document对象方法，将文档保存为pdf格式
			System.out.println("转换文档 [" + inputFile + "] >>> [" + pdfFile + "]");
			// Excel 不能调用SaveAs方法
			Dispatch.call(excel, "ExportAsFixedFormat", xlFormatPDF, pdfFile);

			long end = System.currentTimeMillis();

			System.out.println("用时：" + (end - start) + "ms.");
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("========Error:文档转换失败：" + e.getMessage());
		} finally {
			Dispatch.call(excel, "Close", false);
			System.out.println("关闭文档");
			if (app != null)
				app.invoke("Quit", new Variant[] {});
		}
		ComThread.Release();
		ComThread.quitMainSTA();
		return false;
	}

	private boolean doc2Docx(String inputFile, String destFile) {
		ComThread.InitSTA();

		long start = System.currentTimeMillis();
		ActiveXComponent app = null;
		Dispatch doc = null;
		try {
			app = new ActiveXComponent("Word.Application");// 创建一个word对象
			app.setProperty("Visible", new Variant(false)); // 不可见打开word
			app.setProperty("AutomationSecurity", new Variant(3)); // 禁用宏
			Dispatch docs = app.getProperty("Documents").toDispatch();// 获取文挡属性

			System.out.println("打开文档 >>> " + inputFile);
			// Object[]第三个参数是表示“是否只读方式打开”
			// 调用Documents对象中Open方法打开文档，并返回打开的文档对象Document
			doc = Dispatch.call(docs, "Open", inputFile, false, true).toDispatch();
			// 调用Document对象的SaveAs方法，将文档保存为pdf格式
			System.out.println("转换文档 [" + inputFile + "] >>> [" + destFile + "]");
			Dispatch.call(doc, "SaveAs", destFile, 12);// doc保存为docx格式宏，值为12

			long end = System.currentTimeMillis();

			System.out.println("用时：" + (end - start) + "ms.");
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("========Error:文档转换失败：" + e.getMessage());
		} finally {
			Dispatch.call(doc, "Close", false);
			System.out.println("关闭文档");
			if (app != null)
				app.invoke("Quit", new Variant[] {});
		}
		// 如果没有这句话,winword.exe进程将不会关闭
		ComThread.Release();
		ComThread.quitMainSTA();
		return true;
	}

	private boolean docx2Doc(String inputFile, String destFile) {
		ComThread.InitSTA();

		long start = System.currentTimeMillis();
		ActiveXComponent app = null;
		Dispatch doc = null;
		try {
			app = new ActiveXComponent("Word.Application");// 创建一个word对象
			app.setProperty("Visible", new Variant(false)); // 不可见打开word
			app.setProperty("AutomationSecurity", new Variant(3)); // 禁用宏
			Dispatch docs = app.getProperty("Documents").toDispatch();// 获取文挡属性

			System.out.println("打开文档 >>> " + inputFile);
			// Object[]第三个参数是表示“是否只读方式打开”
			// 调用Documents对象中Open方法打开文档，并返回打开的文档对象Document
			doc = Dispatch.call(docs, "Open", inputFile, false, true).toDispatch();
			// 调用Document对象的SaveAs方法，将文档保存为pdf格式
			System.out.println("转换文档 [" + inputFile + "] >>> [" + destFile + "]");
			Dispatch.call(doc, "SaveAs", destFile, 0);// docx保存为doc格式宏，值为0

			long end = System.currentTimeMillis();

			System.out.println("用时：" + (end - start) + "ms.");
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("========Error:文档转换失败：" + e.getMessage());
		} finally {
			Dispatch.call(doc, "Close", false);
			System.out.println("关闭文档");
			if (app != null)
				app.invoke("Quit", new Variant[] {});
		}
		// 如果没有这句话,winword.exe进程将不会关闭
		ComThread.Release();
		ComThread.quitMainSTA();
		return false;
	}

	public void seekFile(File sourceDir, File destDir) {

		if (sourceDir == null || !sourceDir.exists()) {
			System.out.println(sourceDir.getPath() + ":原目录不存在");
			return;
		} else if (destDir == null || !destDir.exists()) {
			System.out.println(destDir.getPath() + ":结果目录不存在");
			return;
		} else if (sourceDir.isDirectory()) {
			for (File f0 : sourceDir.listFiles()) {
				if (f0.isFile() || (f0.isDirectory() && this.isIndent == false))
					seekFile(f0, destDir);
				else {
					seekFile(f0, new File(destDir.getPath() + File.separator + f0.getName()));
				}
			}
		} else {
			String sourceType = this.getFileSufix(sourceDir.getName());
			String namewoSuffix = this.getNameWithoutSuffix(sourceDir.getName());

			// 不需要转化的情况
			if (sourceType.equalsIgnoreCase(this.destType)) {
				System.out.println(sourceDir.getPath() + " not need to convert!");
				return;
			}
			// 如果文件名重复，就加一个后缀提醒
			String destFile = destDir.getPath() + File.separator + namewoSuffix + "." + destType;
			File destFileTmp = new File(destFile);
			if (destFileTmp.exists())
				destFile += System.currentTimeMillis();
			// doc2Docx
			if ("doc".equalsIgnoreCase(sourceType) && "docx".equalsIgnoreCase(destType)) {
				this.doc2Docx(sourceDir.getPath(), destFile);
			} // docx2Doc
			else if ("docx".equalsIgnoreCase(sourceType) && "doc".equalsIgnoreCase(destType)) {
				this.docx2Doc(sourceDir.getPath(), destFile);
			} // 2pdf
			else if ("pdf".equalsIgnoreCase(this.destType)) {
				convert2PDF(sourceDir.getPath(), destFile);
			}
		}
	}

	private void seekFile(String f1, String f2) {
		File sf = new File(f1);
		File df = new File(f2);
		this.seekFile(sf, df);
	}

	public static void main(String[] args) {
		// TODO 文件夹 缩进
		System.out.println("java -jar webTest.jar destFormat soureDir destDir");
		System.out.println("eg:java -jar webTest.jar pdf d:/tmp d:/dest");

		Convert c = new Convert();
		c.destType = args[0];

		String f1 = args[1];
		String f2 = args[2];

		if (f1 == null || f1.trim().length() == 0) {
			System.out.println(f1 + ":原目录不能为空");
			return;
		} else if (f2 == null || f2.trim().length() == 0) {
			System.out.println(f2 + ":结果目录不能为空");
			return;
		} else if ("doc".equalsIgnoreCase(c.destType) || "docx".equalsIgnoreCase(c.destType)
				|| "pdf".equalsIgnoreCase(c.destType)) {
			c.seekFile(f1, f2);
		} else {
			System.out.println("目标格式只能是：pdf，doc，docx");
		}
		File file = new File("E:\\在线学校");
		System.out.println(file.getName());
	}

}
